Micron Document
Fox's Git Mirrors

Node / rns-mirrors / LXMFy.git rns://e35de29a61974cd952fde3fe9c8500d5/rns-mirrors/LXMFy.git


>LXMFy

Easily create LXMF bots for the Reticulum Network with this extensible framework.


Feature

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Category β”‚ Key Capabilities β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Core β”‚ Interactive CLI, Command Prefixes, Cron-style Task Scheduler, Middleware & Event… β”‚
β”‚ Connectivity β”‚ Direct Delivery & Propagation Fallback, Auto-Peering, RNS Link Support, Opportun… β”‚
β”‚ Security β”‚ Spam Protection, Role-based Permissions, Identity Pinning, Message Signing/Verif… β”‚
β”‚ NLP β”‚ Local NLP Intent Classification (Offline/Private), Type-hinted Argument Parsing β”‚
β”‚ Extensions β”‚ Python Cogs, External Script Cogs (Bash, Go, C, etc.), Linux Sandboxing (Landloc… β”‚
β”‚ Storage β”‚ Extensible Backends (JSON, SQLite, In-Memory), Message Persistence (Crash Recove… β”‚
β”‚ Reliability β”‚ Extensive Stability & Mathematical Stress Testing, Chaos Engineering, Resource L… β”‚
β”‚ UX β”‚ Help on First Message, Auto-generated Help Menus, Customizable Bot Icons, Attach… β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Installation

Requirements: Python 3.11+, RNS 1.3.8+, LXMF 1.0.1+, cbor2 5.4.0+ (installed automatically with LXMFy).

There are many ways to install LXMFy, you pick:

From PyPI

T282828
# pip
pip install lxmfy

# pipx
pipx install lxmfy

Development Installation

For development, clone the repository and install with poetry:

T282828
git clone https://git.quad4.io/LXMFy/LXMFy.git
cd LXMFy

T282828
poetry install

Usage

T282828
lxmfy

Create bots:

T282828
lxmfy create

Debug send/receive:

T282828
lxmfy debug
lxmfy debug --config ./config --output ./lxmfy-debug-report.txt
lxmfy debug probe <destination_hash> --request-path --wait 30
lxmfy debug send <destination_hash>
lxmfy debug receive
lxmfy debug compare <hash_a> <hash_b>

Doctor mode prints a verdict and next steps, then categorized checks (OS, shared vs owned instance, disk permissions, interfaces, announce, send pipeline / storage history, receive readiness). It saves a privacy-redacted T383838lxmfy-debug-*.txt you can share. Colors auto-disable when not a TTY, when T383838NO_COLOR is set, or when Windows VT is unavailable. Use T383838--no-color or T383838NO_COLOR=1 for plain output.

Docker

Building Manually

To build the Docker image, navigate to the root of the project and run:

T282828
docker build -t lxmfy-test .

Once built, you can run the Docker image:

T282828
docker run -d \\
--name lxmfy-test-bot \\
-v $(pwd)/config:/bot/config \\
-v $(pwd)/.reticulum:/root/.reticulum \\
--restart unless-stopped \\
lxmfy-test

Auto-Interface support (network host):

T282828
docker run -d \\
--name lxmfy-test-bot \\
--network host \\
-v $(pwd)/config:/bot/config \\
-v $(pwd)/.reticulum:/root/.reticulum \\
--restart unless-stopped \\
lxmfy-test

Building Wheels with docker/Dockerfile.Build

The T383838docker/Dockerfile.Build is used to build the T383838lxmfy Python package into a wheel file within a Docker image.

T282828
docker build -f docker/Dockerfile.Build -t lxmfy-wheel-builder .

This will create an image named T383838lxmfy-wheel-builder. To extract the built wheel file from the image, you can run a container from this image and copy the T383838dist directory:

T282828
docker run --rm -v "$(pwd)/dist_output:/output" lxmfy-wheel-builder

This command will create a T383838dist_output directory in your current working directory and copy the built wheel file into it.

Example

T282828
from lxmfy import LXMFBot, load_cogs_from_directory

bot = LXMFBot(
name="LXMFy Test Bot", # Name of the bot that appears on the network.
announce=5400, # Announce every hour, set to 0 to disable.
announce_enabled=True, # Set to False to disable all announces (both initial and periodic)
announce_immediately=True, # Set to False to disable initial announce
admins=["your_lxmf_hash_here"], # List of admin hashes.
hot_reloading=True, # Enable hot reloading.
command_prefix="/", # Set to None to process all messages as commands.
cogs_dir="cogs", # Specify cogs directory name.
rate_limit=5, # 5 messages per minute
cooldown=5, # 5 seconds cooldown
max_warnings=3, # 3 warnings before ban
warning_timeout=300, # Warnings reset after 5 minutes
signature_verification_enabled=True, # Enable cryptographic signature verification
require_message_signatures=False, # Allow unsigned messages but log them
propagation_fallback_enabled=True, # Enable propagation fallback after direct delivery fails
propagation_node="your_propagation_node_hash_here", # Manual propagation node (optional)
autopeer_propagation=True, # Auto-discover propagation nodes (optional)
autopeer_maxdepth=4, # Max hops for auto-peering (default: 4)
enable_propagation_node=False, # Run as propagation node (default: False)
message_storage_limit_mb=500, # Storage limit in MB for propagation node (default: 500)
direct_delivery_retries=3, # Number of direct delivery attempts before falling back to propagation
landlock_enabled=True, # Linux Landlock LSM sandbox for the bot process (default)
external_cogs_sandbox_enabled=True, # Sandbox external script cogs on Linux
external_cogs_sandbox_type="auto", # auto, landlock, bwrap, firejail, or none
)

# Dynamically load all cogs
load_cogs_from_directory(bot)

@bot.command(name="ping", description="Test if bot is responsive")
def ping(ctx):
ctx.reply("Pong!")

# Admin Only Command
@bot.command(name="echo", description="Echo a message", admin_only=True)
def echo(ctx, message: str):
ctx.reply(message)

bot.run()

RRC (Reticulum Relay Chat)

Bots can join RRC hubs as ordinary clients over RNS Links with CBOR envelopes:

T282828
from lxmfy import LXMFBot, RRCMessage

bot = LXMFBot(
name="RoomBot",
rrc_enabled=True,
rrc_hubs=["your_rrc_hub_destination_hash"],
rrc_rooms=["lobby"],
rrc_nick="RoomBot",
)

@bot.on_rrc
def on_rrc(event, client, payload):
if event == "msg" and isinstance(payload, RRCMessage) and payload.mention:
client.send_message(payload.room, f"Heard you, {payload.nick}")

bot.run()

Or connect at runtime with T383838bot.connect_rrc(hub_hash, rooms=["lobby"]).

Hub sessions persist across restarts by default (T383838rrc_persist_sessions=True). Outgoing LXMF messages are also persisted by default (T383838message_persistence_enabled=True) so a crash mid-queue does not drop them. The outbound queue is bounded (T383838message_queue_size, default 50) and drops the oldest message when full.

Propagation Node Configuration

LXMFy supports three modes for propagation node usage:

1. Manual Configuration

Set a specific propagation node by hash:

T282828
bot = LXMFBot(
name="MyBot",
propagation_fallback_enabled=True,
propagation_node="your_propagation_node_hash_here", # Manual node configuration
direct_delivery_retries=3,
)

2. Automatic Discovery (Auto-Peering)

Let the bot automatically discover and use propagation nodes from network announces:

T282828
bot = LXMFBot(
name="MyBot",
propagation_fallback_enabled=True,
autopeer_propagation=True, # Enable automatic discovery
autopeer_maxdepth=4, # Maximum hop distance for auto-peering (default: 4)
)

The bot will listen for propagation node announces and automatically peer with suitable nodes within the configured hop depth.

3. Run as Propagation Node

Your bot can act as a propagation node itself to store and forward messages:

T282828
bot = LXMFBot(
name="MyPropagationBot",
enable_propagation_node=True, # Enable propagation node mode
message_storage_limit_mb=500, # Limit storage to 500 MB (default)
)

When running as a propagation node, the bot will store messages for offline users and forward them when the recipients come online. The T383838message_storage_limit_mb prevents the bot from consuming unlimited disk space. Set to 0 for unlimited storage (not recommended).

Querying Propagation Status

You can check the current propagation configuration and discovered nodes:

T282828
status = bot.get_propagation_node_status()
print(f"Current outbound node: {status['current_outbound_node']}")
print(f"Discovered peers: {status['discovered_peers']}")

Dynamically Setting Propagation Node

You can change the propagation node at runtime:

T282828
bot.set_propagation_node("new_propagation_node_hash")

Managing Storage Limits

When running as a propagation node, you can query and adjust storage limits:

T282828
# Get current storage statistics
stats = bot.get_propagation_storage_stats()
print(f"Storage used: {stats['storage_size_mb']:.2f} MB")
print(f"Storage limit: {stats['storage_limit_mb']} MB")
print(f"Utilization: {stats['utilization_percent']:.1f}%")
print(f"Messages stored: {stats['message_count']}")

# Change storage limit at runtime
bot.set_message_storage_limit(megabytes=1000) # Set to 1 GB

Important Notes

β€’ Without configuring propagation (manual, auto-peer, or running as a node), messages requiring propagation will fail
β€’ You can combine modes: e.g., set a manual node AND enable auto-peering as backup
β€’ When running as a propagation node, your bot can still send and receive messages normally
β€’ Auto-peering respects the T383838autopeer_maxdepth setting to avoid connecting to distant nodes

Security & Sandboxing

On Linux kernels with Landlock support (5.13+), LXMFy can restrict filesystem access for the bot process and for external script cogs.

Bot process sandbox

When T383838landlock_enabled=True (default), the bot applies a Landlock LSM sandbox after startup. System paths are read-only; bot storage, config, cogs, Reticulum config, and temp directories remain writable.

T282828
bot = LXMFBot(
name="SecureBot",
landlock_enabled=True,
)

status = bot.get_landlock_status()
print(status)

Environment overrides:

β€’ T383838LXMFY_LANDLOCK=0 β€” disable Landlock
β€’ T383838LXMFY_LANDLOCK=1 β€” force an attempt on Linux
β€’ unset β€” follow T383838landlock_enabled and kernel auto-detection

External script cog sandbox

Executable cogs in T383838cogs/ can run in a restricted environment when T383838external_cogs_sandbox_enabled=True (default). Set T383838external_cogs_sandbox_type to:

β€’ T383838auto (default) β€” prefer Landlock, then T383838bwrap, then T383838firejail
β€’ T383838landlock β€” Landlock-only via T383838preexec_fn
β€’ T383838bwrap β€” bubblewrap read-only bind sandbox
β€’ T383838firejail β€” firejail private profile with no network
β€’ T383838none β€” no subprocess sandbox

See the docs for full configuration details.

Development

β€’ Python 3.11+
β€’ Poetry

T282828
poetry install
poetry run lxmfy run echo

Common Makefile targets:

T282828
make lint # ruff check
make typecheck # pyright lxmfy
make test # pytest
make ci # lint, typecheck, security check, test, build

Contributing

For now send ideas and issues to LXMF: T3838387cc8d66b4f6a0e0e49d34af7f6077b5a

License
Served by rngit 1.4.1 - Generated in 0.11s